#include "stdafx.h"
#include "RenderVideo.h"
#include "IrrDevice.h"
#include "irrMath.h"

CRenderVideo*	CRenderVideo::m_pInstance = NULL;

CRenderVideo::CRenderVideo()
{}

CRenderVideo::~CRenderVideo()
{}




void CRenderVideo::DrawTriangle(const core::position2df& pos1, const core::position2df& pos2, const core::position2df& pos3, const video::SColor& color)
{
	m_Vertices[0].Pos.set(pos1.X, pos1.Y, 0);
	m_Vertices[1].Pos.set(pos2.X, pos2.Y, 0);
	m_Vertices[2].Pos.set(pos3.X, pos3.Y, 0);

	m_Vertices[0].Color = color;
	m_Vertices[1].Color = color;
	m_Vertices[2].Color = color;

	s16 indexlist[3] = {0, 1, 2};

	CIrrDevice::GetVideoDriver()->drawVertexPrimitiveList(m_Vertices, indexlist, 0, 3, 1, video::EVT_STANDARD, scene::EPT_TRIANGLES, video::EIT_16BIT);

}

void CRenderVideo::DrawRectangle(const core::rect<float>& rect, const video::SColor& color, const core::position2df& pos)
{	
	m_Vertices[0].Pos.set(pos.X + rect.UpperLeftCorner.X, pos.Y + rect.UpperLeftCorner.Y, 0);
	m_Vertices[1].Pos.set(pos.X + rect.UpperLeftCorner.X, pos.Y + rect.LowerRightCorner.Y, 0);
	m_Vertices[2].Pos.set(pos.X + rect.LowerRightCorner.X, pos.Y + rect.LowerRightCorner.Y, 0);
	m_Vertices[3].Pos.set(pos.X + rect.LowerRightCorner.X, pos.Y + rect.UpperLeftCorner.Y, 0);

	m_Vertices[0].Color = color;
	m_Vertices[1].Color = color;
	m_Vertices[2].Color = color;
	m_Vertices[3].Color = color;

	s16 indexlist[6] = {0, 1, 2, 0, 2, 3};

	CIrrDevice::GetVideoDriver()->drawVertexPrimitiveList(m_Vertices, indexlist, 0, 6, 2, video::EVT_STANDARD, scene::EPT_TRIANGLES, video::EIT_16BIT);
}


void CRenderVideo::DrawPolygon(const core::position2df* vectices, const video::SColor& color, int indexCount)
{
	if(indexCount > VER_BUFFER_MAX)
	{
		return;
	}

	s16* indexlist = new s16[indexCount];
	for(int i = 0; i < indexCount; i++)
	{
		m_Vertices[i].Pos.set(vectices[i].X, vectices[i].Y, 0);
		m_Vertices[i].Color = color;
		indexlist[i] = i;
	}

	CIrrDevice::GetVideoDriver()->drawVertexPrimitiveList(m_Vertices, indexlist, 0, indexCount, indexCount - 2, video::EVT_STANDARD, scene::EPT_TRIANGLE_FAN, video::EIT_16BIT);

	delete[] indexlist;
	indexlist = 0;
}


void CRenderVideo::DrawCircle(const core::position2df& center, const f32& radius, const video::SColor& color, const s32& segement)
{
	if(segement + 2 > VER_BUFFER_MAX)
	{
		return;
	}

	s32 indexCount = segement + 2;
	s16* indexlist = new s16[indexCount];
	f32 angle = 0.f;
	const f32 increment = 2 * PI / segement;

	m_Vertices[0].Pos.set(center.X, center.Y, 0);
	m_Vertices[0].Color = color;
	indexlist[0] = 0;
	for(int i = 1; i < indexCount; i++)
	{
		m_Vertices[i].Pos.set(center.X + cosf(angle) * radius, center.Y + sinf(angle) * radius, 0);
		m_Vertices[i].Color = color;
		indexlist[i] = i;
		angle += increment;
	}

	CIrrDevice::GetVideoDriver()->drawVertexPrimitiveList(m_Vertices, indexlist, 0, indexCount, indexCount - 2, video::EVT_STANDARD, scene::EPT_TRIANGLE_FAN, video::EIT_16BIT);

	delete[] indexlist;
	indexlist = 0;

}

void CRenderVideo::DrawLine(const irr::core::position2df &pos1, const irr::core::position2df &pos2, const irr::video::SColor &color)
{
	CIrrDevice::GetVideoDriver()->draw2DLine(pos1, pos2, color);
}

void CRenderVideo::DrawLine(const float x1, const float y1, const float x2, const float y2, const irr::video::SColor &color)
{
	DrawLine(core::position2df(x1, y1), core::position2df(x2, y2), color);
}

void CRenderVideo::DrawTriangleLine(const irr::core::position2df &pos1, const irr::core::position2df &pos2, const irr::core::position2df &pos3, const irr::video::SColor &color)
{
	DrawLine(pos1, pos2, color);
	DrawLine(pos1, pos3, color);
	DrawLine(pos2, pos3, color);
}

void CRenderVideo::DrawRectangleLine(const irr::core::rect<float> &rect, const irr::video::SColor &color, const irr::core::position2df &pos)
{
	DrawLine(core::position2df(pos.X + rect.UpperLeftCorner.X, pos.Y + rect.UpperLeftCorner.Y), core::position2df(pos.X + rect.UpperLeftCorner.X, pos.Y + rect.LowerRightCorner.Y),color);
	DrawLine(core::position2df(pos.X + rect.UpperLeftCorner.X, pos.Y + rect.LowerRightCorner.Y), core::position2df(pos.X + rect.LowerRightCorner.X, pos.Y + rect.LowerRightCorner.Y),color);
	DrawLine(core::position2df(pos.X + rect.LowerRightCorner.X, pos.Y + rect.LowerRightCorner.Y), core::position2df(pos.X + rect.LowerRightCorner.X, pos.Y + rect.UpperLeftCorner.Y),color);
	DrawLine(core::position2df(pos.X + rect.LowerRightCorner.X, pos.Y + rect.UpperLeftCorner.Y), core::position2df(pos.X + rect.UpperLeftCorner.X, pos.Y + rect.UpperLeftCorner.Y),color);
}

void CRenderVideo::DrawPolygonLine(const irr::core::position2df *vertices, const irr::video::SColor &color, int indexCount)
{
	int i = 0;
	for(i = 0; i < indexCount - 1; i++)
	{
		DrawLine(vertices[i], vertices[i+1], color);
	}
	DrawLine(vertices[i], vertices[0], color);
}

void CRenderVideo::DrawCircleLine(const irr::core::position2df &center, const irr::f32 &radius, const irr::video::SColor &color, const irr::s32 &segement)
{
	if(segement > VER_BUFFER_MAX)
	{
		return;
	}

	int i = 0;
	s32 indexCount = segement;	
	f32 angle = 0.f;
	const f32 increment = 2 * PI / segement;

	
	for(i = 0; i < indexCount; i++)
	{
		m_Vertices2D[i] = core::position2df(center.X + cosf(angle) * radius, center.Y + sinf(angle) * radius);		
		angle += increment;
	}

	DrawPolygonLine(m_Vertices2D, color, indexCount);

}

//b2 drawing

void CRenderVideo::DrawPolygonB2(const b2Vec2* vertices, int32 vertexCount, const b2Color& color)
{
	int i = 0;
	for(i = 0; i < vertexCount - 1; i++)
	{
		DrawLine(vertices[i].x, vertices[i].y, vertices[i+1].x, vertices[i+1].y, video::SColor(255, 0, 255, 255));
	}
	DrawLine(vertices[i].x, vertices[i].y, vertices[0].x, vertices[0].y, video::SColor(255, 0, 255, 255));
}

void CRenderVideo::DrawSolidPolygonB2(const b2Vec2* vertices, int32 vertexCount, const b2Color& color)
{}

void CRenderVideo::DrawCircleB2(const b2Vec2& center, float32 radius, const b2Color& color)
{
	int segement = 32;
	int i = 0;
	s32 indexCount = segement;	
	f32 angle = 0.f;
	const f32 increment = 2 * PI / segement;
	
	for(i = 0; i < indexCount; i++)
	{
		m_Vertices2D[i] = core::position2df(center.x + cosf(angle) * radius, center.y + sinf(angle) * radius);		
		angle += increment;
	}

	DrawPolygonLine(m_Vertices2D, video::SColor(255, 0, 255, 255), indexCount);
}

void CRenderVideo::DrawSolidCircleB2(const b2Vec2& center, float32 radius, const b2Vec2& axis, const b2Color& color)
{}

void CRenderVideo::DrawSegmentB2(const b2Vec2& p1, const b2Vec2& p2, const b2Color& color)
{}


CRenderVideo* CRenderVideo::GetInstance()
{
	if(m_pInstance)
	{
		return m_pInstance;
	}
	else
	{
		m_pInstance = NEW CRenderVideo();
		return m_pInstance;
	}
}